package IO.序列化;
/*
Jackson 的核心模块由三部分组成。

•jackson-core，核心包，提供基于"流模式"解析的相关 API，它包括 JsonPaser 和 JsonGenerator。 Jackson 内部实现正是通过高性能的流模
  式 API 的 JsonGenerator 和 JsonParser 来生成和解析 json。
•jackson-annotations，注解包，提供标准注解功能；
•jackson-databind ，数据绑定包， 提供基于"对象绑定" 解析的相关 API （ ObjectMapper ） 和"树模型" 解析的相关 API （JsonNode）；基于"对象绑定" 解
  析的 API 和"树模型"解析的 API 依赖基于"流模式"解析的 API。

maven依赖：
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-core</artifactId>
	<version>2.14.3</version>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-databind</artifactId>
	<version>2.14.3</version>
</dependency>
<dependency>
	<groupId>com.fasterxml.jackson.core</groupId>
	<artifactId>jackson-annotations</artifactId>
	<version>2.14.3</version>
</dependency>
*/

import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.fasterxml.jackson.databind.ObjectMapper;

import lombok.Data;
import com.fasterxml.jackson.core.type.TypeReference;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.*;
import com.fasterxml.jackson.databind.JsonNode;
import java.util.HashMap;
import java.util.Map;
import java.io.Reader;
import java.io.StringReader;
import java.io.InputStream;
import java.io.FileInputStream;
import java.net.URI;
import java.net.URL;
/*
//JAVA对象转JSON[JSON序列化]
public class Jackson使用 {
    public static void main(String[] args) throws ParseException, IOException {
        User user = new User();
        user.setName("zhangsan");
        user.setEmail("zhangsan@163.com");
        user.setAge(20);

        SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
        user.setBirthday(dateformat.parse("2023-06-05"));

//         ObjectMapper是JSON操作的核心，Jackson的所有JSON操作都是在ObjectMapper中实现。
//         ObjectMapper有多个JSON序列化的方法，可以把JSON字符串保存File、OutputStream等不同的介质中。
//         writeValue(File arg0, Object arg1)把arg1转成json序列，并保存到arg0文件中。
//         writeValue(OutputStream arg0, Object arg1)把arg1转成json序列，并保存到arg0输出流中。
//         writeValueAsBytes(Object arg0)把arg0转成json序列，并把结果输出成字节数组。
//         writeValueAsString(Object arg0)把arg0转成json序列，并把结果输出成字符串。
//         
        ObjectMapper mapper = new ObjectMapper();

        //User类转JSON
        //输出结果：{"name":"zhangsan","age":20,"birthday":844099200000,"email":"zhangsan@163.com"}
        String json = mapper.writeValueAsString(user);//把user转成json序列，并把结果输出成字符串。
        System.out.println(json);//{"name":"zhangsan","age":20,"birthday":1685894400000,"email":"zhangsan@163.com"}

        //Java集合转JSON
        //输出结果：[{"name":"zhangsan","age":20,"birthday":844099200000,"email":"zhangsan@163.com"}]
        List<User> users = new ArrayList<User>();
        users.add(user);
        String jsonlist = mapper.writeValueAsString(users);
        System.out.println(jsonlist);//[{"name":"zhangsan","age":20,"birthday":1685894400000,"email":"zhangsan@163.com"}]
    }
}
*/
/*
JSON转Java类[JSON反序列化]
ObjectMapper objectMapper = new ObjectMapper();
•readValue(Reader reader, Class cls) 从Reader读取对象
String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 4 }";
Reader reader = new StringReader(carJson);
Car car = objectMapper.readValue(reader, Car.class);

•readValue(File file, Class cls) 从File中读取对象
File file = new File("data/car.json");
Car car = objectMapper.readValue(file, Car.class);

•readValue(URL url, Class cls) 从URL中读取对象
URL url = new URL("file:data/car.json");
Car car = objectMapper.readValue(url, Car.class);

•objectMapper.readValue(InputStream input, Class cls);
InputStream input = new FileInputStream("data/car.json");
Car car = objectMapper.readValue(input, Car.class);

•readValue(Byte[] bytes, Class cls) 从字节数组中读取对象
String carJson = "{\"brand\":\"Mercedes\", \"doors\":5}";
byte[] bytes = carJson.getBytes("UTF-8");
Car car = objectMapper.readValue(bytes, Car.class);

•readValue(String jsonArray, Class[] cls) 从JSON数组字符串中读取对象数组
String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
Car[] cars2 = objectMapper.readValue(jsonArray, Car[].class);

•objectMapper.readValue(String jsonArray，new TypeReference <List <Object>>(){}) 从JSON数组字符串中读取对象列表
String jsonArray ="[{\"brand\":\"ford\"}，{\"brand\":\"Fiat\"}]";
List <Car> cars1 = objectMapper.readValue(jsonArray，new TypeReference <List <Car >>(){});

•objectMapper.readValue(String jsonObject，new TypeReference <Map <String，Object >>(){}) 从JSON字符串中读取映射为map
String jsonObject ="{\"brand\":\"ford\",\"doors\":5}";
Map <String，Object> jsonMap = objectMapper.readValue(jsonObject,new TypeReference <Map <String,Object>>(){});

*/
/*
public class Jackson使用 {
    public static void main(String[] args) throws ParseException, IOException {
        String json = "{\"name\":\"zhangsan\",\"age\":20,\"birthday\":1685894400000,\"email\":\"zhangsan@163.com\"}";
        //ObjectMapper支持从byte[]、File、InputStream、字符串等数据的JSON反序列化。
        ObjectMapper mapper = new ObjectMapper();
        User user = mapper.readValue(json, User.class);
        System.out.println(user);
    }
}*/
//User{name='zhangsan', age=20, birthday=Mon Jun 05 00:00:00 CST 2023, email='zhangsan@163.com'}
/*
public class Jackson使用 {
	//public static ObjectMapper mapper = new ObjectMapper();
	static ObjectMapper mapper = new ObjectMapper();
   public static void main(String[] args) throws ParseException, IOException {
       String json = "[{\"name\":\"zhangsan\",\"age\":20,\"birthday\":1685894400000,\"email\":\"zhangsan@163.com\"}]";
       List<User> beanList = mapper.readValue(json, new TypeReference<List<User>>() {});
       System.out.println(beanList);//[User{name='zhangsan', age=20, birthday=Mon Jun 05 00:00:00 CST 2023, email='zhangsan@163.com'}]
   
   
   }
}
*/
@Data
class Car {
	 private String brand = null;
	 private int doors = 0;

//	    public String getBrand() { return this.brand; }
//	    public void   setBrand(String brand){ this.brand = brand;}
//
//	    public int  getDoors() { return this.doors; }
//	    public void setDoors (int doors) { this.doors = doors; }
}

public class Jackson使用 {
	static ObjectMapper mapper = new ObjectMapper();
   public static void main(String[] args) throws ParseException, IOException {
   	//JSON字符串-->Java对象
   	String carJson = "{ \"brand\" : \"Mercedes\", \"doors\" : 5 }";
   	Car car = mapper.readValue(carJson, Car.class);
   	System.out.println(car);

   	//将Json转换为Car类对象：
   	try {
   	    Car car1 = mapper.readValue(carJson, Car.class);
   	    System.out.println("car1 brand = " + car1.getBrand());
   	    System.out.println("car1 doors = " + car1.getDoors());
   	} catch (IOException e) {
   		e.printStackTrace();
   	}
   	
   	//JSON 字符输入流-->Java对象
   	Reader reader = new StringReader(carJson);
   	Car car2 = mapper.readValue(reader, Car.class);
   	System.out.println(car2);
   	
   	//JSON文件-->Java对象
   	File file = new File("f:\\Car.json");
   	Car car3 = mapper.readValue(file, Car.class);
   	System.out.println(car3);
   	
   	//JSON via URL--->Java对象
 //  	URL url = new URL("file:f:\\Car.json");
   	URI uri=file.toURI();
   	System.out.println("URI----"+uri);
   	URL url=uri.toURL();
   	System.out.println("URL：                  " + url.toString());
      System.out.println("protocol：        " + url.getProtocol());
      System.out.println("Authority：      " + url.getAuthority());
      System.out.println("file name：      " + url.getFile());
      System.out.println("host：                " + url.getHost());
      System.out.println("path：                " + url.getPath());
      System.out.println("port：                " + url.getPort());
      System.out.println("default port：" + url.getDefaultPort());
      System.out.println("query：              " + url.getQuery());
      System.out.println("ref：                  " + url.getRef());
   	System.out.println("URL----"+url);
   	Car car4 = mapper.readValue(url, Car.class);
   	System.out.println("car4: "+car4);
   	
   	//JSON字节输入流-->Java对象
   	InputStream input = new FileInputStream("f:\\Car.json");
   	Car car5 = mapper.readValue(input, Car.class);
   	System.out.println(car5);

   	//JSON二进制数组-->Java对象
   	byte[] bytes = carJson.getBytes("UTF-8");
   	Car car6 = mapper.readValue(bytes, Car.class);
   	System.out.println(car6);
   	
   	//JSON数组字符串-->Java对象数组
   	String jsonArray = "[{\"brand\":\"ford\"}, {\"brand\":\"Fiat\"}]";
   	Car[] cars7 = mapper.readValue(jsonArray, Car[].class);
   	System.out.println(Arrays.toString(cars7));
   	
   	//JSON数组字符串-->List
   	List<Car> cars8 = mapper.readValue(jsonArray, new TypeReference<List<Car>>(){});
   	System.out.println(cars8);
   	
   	//JSON字符串-->Map
   	String jsonObject = "{\"brand\":\"ford\", \"doors\":5}";
   	Map<String, Object> jsonMap = mapper.readValue(jsonObject,new TypeReference<Map<String,Object>>(){});
   	System.out.println(jsonMap);
   	
   }
}
/*

 */
/*
自定义序列化和反序列化
当 Jackson 默认序列化和反序列化不能满足实际的开发需要时，可以自定义新的序列化和反序列化类。

自定义的序列化类需要继承 StdSerializer，同时重写 serialize() 方法，利用 JsonGenerator 生成 JSON，示例如下：

public class CustomSerializer extends StdSerializer<Man> {
    protected CustomSerializer(Class<Man> t) {
        super(t);
    }

    public CustomSerializer() {
        this(null);
    }

    @Override
    public void serialize(Man value, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();
        gen.writeStringField("name", value.getName());
        gen.writeEndObject();
    }
}

class Man{
    private int age;
    private String name;

    public Man(int age, String name) {
        this.age = age;
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
定义好自定义序列化类后，要想在程序中调用它们，需要将其注册到 ObjectMapper 的 Module 中，示例如下所示：

ObjectMapper mapper = new ObjectMapper();
SimpleModule module =
        new SimpleModule("CustomSerializer", new Version(1, 0, 0, null, null, null));
module.addSerializer(Man.class, new CustomSerializer());
mapper.registerModule(module);
Man man = new Man( 18,"沉默王二");
String json = mapper.writeValueAsString(man);
System.out.println(json);
程序输出结果如下所示：

{"name":"沉默王二"}
自定义序列化类 CustomSerializer 中没有添加 age 字段，所以只输出了 name 字段。

再来看一下自定义的反序列化类，继承 StdDeserializer，同时重写 deserialize() 方法，利用 JsonGenerator 读取 JSON，示例如下：

public class CustomDeserializer extends StdDeserializer<Woman> {
    protected CustomDeserializer(Class<?> vc) {
        super(vc);
    }

    public CustomDeserializer() {
        this(null);
    }

    @Override
    public Woman deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonNode node = p.getCodec().readTree(p);
        Woman woman = new Woman();
        int age = (Integer) ((IntNode) node.get("age")).numberValue();
        String name = node.get("name").asText();
        woman.setAge(age);
        woman.setName(name);
        return woman;
    }
}
class Woman{
    private int age;
    private String name;

    public Woman() {
    }

    // getter/setter

    @Override
    public String toString() {
        return "Woman{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
}
通过 JsonNode 把 JSON 读取到一个树形结构中，然后通过 JsonNode 的 get 方法将对应字段读取出来，然后生成新的 Java 对象，并返回。

定义好自定义反序列化类后，要想在程序中调用它们，同样需要将其注册到 ObjectMapper 的 Module 中，示例如下所示：

ObjectMapper mapper = new ObjectMapper();
SimpleModule module =
        new SimpleModule("CustomDeserializer", new Version(1, 0, 0, null, null, null));
module.addDeserializer(Woman.class, new CustomDeserializer());
mapper.registerModule(module);
String json = "{ \"name\" : \"三妹\", \"age\" : 18 }";
Woman woman = mapper.readValue(json, Woman.class);
System.out.println(woman);
程序输出结果如下所示：

Woman{age=18, name='三妹'}
*/





//JSON注解
//Jackson提供了一系列注解，方便对JSON序列化和反序列化进行控制，下面介绍一些常用的注解。
//
//@JsonIgnore 此注解用于属性上，作用是进行JSON操作时忽略该属性。
//@JsonFormat 此注解用于属性上，作用是把Date类型直接转化为想要的格式，
//   如@JsonFormat(pattern = “yyyy-MM-dd HH-mm-ss”)。
//@JsonProperty 此注解用于属性上，作用是把该属性的名称序列化为另外一个名称，
//   如把trueName属性序列化为name，@JsonProperty(“name”)。
/*
public class Jackson {

   public static void main(String[] args) throws ParseException, IOException {
       User1 user = new User1();
       user.setName("zhangsan");
       user.setEmail("zhangsan@163.com");
       user.setAge(20);

       SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd");
       user.setBirthday(dateformat.parse("2023-06-05"));

       ObjectMapper mapper = new ObjectMapper();
       String json = mapper.writeValueAsString(user);
       System.out.println(json);//{"name":"zhangsan","birthday":"2023年06月04日","my_email":"zhangsan@163.com"}
   }
}
*/